﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Collections.Generic;

namespace SLRTHackathon.DataModels
{

    public class SLRTDataContext : DataContext
    {
        // Pass the connection string to the base class.
        public SLRTDataContext(string connectionString) : base(connectionString)
        { }

        // Specify a table for the cars.
        public Table<Car> Cars;

        // Specify a table for the insurances.
        public Table<Insurance> Insurances;

        // Specify a table for the extendedInsurances.
        public Table<ExtendedInsurance> ExtendedInsurances;

        // Specify a table for the customDependencies.
        public Table<CustomDependency> CustomDependencies;

        // Specify a table for the internationalVignettes.
        public Table<InternationalVignette> InternationalVignettes;

    }

        [Table]
        public class Car : INotifyPropertyChanged, INotifyPropertyChanging
        {

            // Define ID: private field, public property, and database column.
            private int _carId;

            [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int CarId
            {
                get { return _carId; }
                set
                {
                    if (_carId != value)
                    {
                        NotifyPropertyChanging("CarId");
                        _carId = value;
                        NotifyPropertyChanged("CarId");
                    }
                }
            }

            // Define identificationName: private field, public property, and database column.
            private String _identificationName;

            [Column]
            public String IdentificationName
            {
                get { return _identificationName; }
                set
                {
                    if (_identificationName != value)
                    {
                        NotifyPropertyChanging("IdentificationName");
                        _identificationName = value;
                        NotifyPropertyChanged("IdentificationName");
                    }
                }
            }

            // Define model: private field, public property, and database column.
            private String _model;

            [Column]
            public String Model
            {
                get { return _model; }
                set
                {
                    if (_model != value)
                    {
                        NotifyPropertyChanging("Model");
                        _model = value;
                        NotifyPropertyChanged("Model");
                    }
                }
            }

            // Define brand: private field, public property, and database column.
            private String _brand;

            [Column]
            public String Brand
            {
                get { return _brand; }
                set
                {
                    if (_brand != value)
                    {
                        NotifyPropertyChanging("Brand");
                        _brand = value;
                        NotifyPropertyChanged("Brand");
                    }
                }
            }

            // Define yearOfFabrication: private field, public property, and database column.
            private Int32 _yearOfFabrication;

            [Column]
            public Int32 YearOfFabrication
            {
                get { return _yearOfFabrication; }
                set
                {
                    if (_yearOfFabrication != value)
                    {
                        NotifyPropertyChanging("YearOfFabrication");
                        _yearOfFabrication = value;
                        NotifyPropertyChanged("YearOfFabrication");
                    }
                }
            }

            // Define CID: private field, public property, and database column.
            private Double _CID;

            [Column]
            public Double CID
            {
                get { return _CID; }
                set
                {
                    if (_CID != value)
                    {
                        NotifyPropertyChanging("CID");
                        _CID = value;
                        NotifyPropertyChanged("CID");
                    }
                }
            }

            // Define CarImage: private field, public property, and database column.
            private String _carImage;

            [Column]
            public String CarImage
            {
                get { return _carImage; }
                set
                {
                    if (_carImage != value)
                    {
                        NotifyPropertyChanging("CarImage");
                        _carImage = value;
                        NotifyPropertyChanged("CarImage");
                    }
                }
            }

            // Define LocalVignetteEndDate: private field, public property, and database column.
            private DateTime _localVignetteEndDate;

            [Column]
            public DateTime LocalVignetteEndDate
            {
                get { return _localVignetteEndDate; }
                set
                {
                    if (_localVignetteEndDate != value)
                    {
                        NotifyPropertyChanging("LocalVignetteEndDate");
                        _localVignetteEndDate = value;
                        NotifyPropertyChanged("LocalVignetteEndDate");
                    }
                }
            }

            // Define NumberOfDaysBeforeEndDate for the localVignette: private field, public property, and database column.
            private Int32 _numberOfDaysBeforeEndDate;

            [Column]
            public Int32 NumberOfDaysBeforeEndDate
            {
                get { return _numberOfDaysBeforeEndDate; }
                set
                {
                    if (_numberOfDaysBeforeEndDate != value)
                    {
                        NotifyPropertyChanging("NumberOfDaysBeforeEndDate");
                        _numberOfDaysBeforeEndDate = value;
                        NotifyPropertyChanged("NumberOfDaysBeforeEndDate");
                    }
                }
            }


            // Define the entity set for the collection side of the relationship.
            private EntitySet<Insurance> _insurances;

            [Association(Storage = "_insurances", OtherKey = "Id", ThisKey = "CarId")]
            public EntitySet<Insurance> Insurances
            {
                get { return this._insurances; }
                set { this._insurances.Assign(value); }
            }

            // Called during an add operation
            private void attach_Insurance(Insurance insurance)
            {
                NotifyPropertyChanging("Insurance");
                insurance.Car = this;
            }

            // Called during a remove operation
            private void detach_Insurance(Insurance insurance)
            {
                NotifyPropertyChanging("Insurance");
                insurance.Car = null;
            }

            //----------- extended insurance
            // Define the entity set for the collection side of the relationship.
            private EntitySet<ExtendedInsurance> _extendedInsurances;

            [Association(Storage = "_extendedInsurances", OtherKey = "Id", ThisKey = "CarId")]
            public EntitySet<ExtendedInsurance> ExtendedInsurances
            {
                get { return this._extendedInsurances; }
                set { this._extendedInsurances.Assign(value); }
            }
            
            // Called during an add operation
            private void attach_ExtendedInsurance(ExtendedInsurance extendedInsurance)
            {
                NotifyPropertyChanging("ExtendedInsurance");
                extendedInsurance.Car = this;
            }

            // Called during a remove operation
            private void detach_ExtendedInsurance(ExtendedInsurance extendedInsurance)
            {
                NotifyPropertyChanging("ExtendedInsurance");
                extendedInsurance.Car = null;
            }

            //----------- custom dependencies
            // Define the entity set for the collection side of the relationship.
            private EntitySet<CustomDependency> _customDependencies;

            [Association(Storage = "_customDependencies", OtherKey = "Id", ThisKey = "CarId")]
            public EntitySet<CustomDependency> CustomDependencies
            {
                get { return this._customDependencies; }
                set { this._customDependencies.Assign(value); }
            }
                       
            // Called during an add operation
            private void attach_CustomDependency(CustomDependency customDependency)
            {
                NotifyPropertyChanging("CustomDependency");
                customDependency.Car = this;
            }

            // Called during a remove operation
            private void detach_CustomDependency(CustomDependency customDependency)
            {
                NotifyPropertyChanging("CustomDependency");
                customDependency.Car = null;
            }

            // Assign handlers for the add and remove operations, respectively.
            public Car()
            {
                _insurances = new EntitySet<Insurance>(
                    new Action<Insurance>(this.attach_Insurance),
                    new Action<Insurance>(this.detach_Insurance)
                    );
                _extendedInsurances = new EntitySet<ExtendedInsurance>(
                    new Action<ExtendedInsurance>(this.attach_ExtendedInsurance),
                    new Action<ExtendedInsurance>(this.detach_ExtendedInsurance)
                    );
                _customDependencies = new EntitySet<CustomDependency>(
                    new Action<CustomDependency>(this.attach_CustomDependency),
                    new Action<CustomDependency>(this.detach_CustomDependency)
                    );
            }


            // Version column aids update performance.
            [Column(IsVersion = true)]
            private Binary _version;

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            #region INotifyPropertyChanging Members

            public event PropertyChangingEventHandler PropertyChanging;

            // Used to notify that a property is about to change
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }

            #endregion
        }


        [Table]
        public class Insurance : INotifyPropertyChanged, INotifyPropertyChanging
        {

            // Define id: private field, public property, and database column.
            private int _id;

            [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int Id
            {
                get { return _id; }
                set
                {
                    if (_id != value)
                    {
                        NotifyPropertyChanging("Id");
                        _id = value;
                        NotifyPropertyChanged("Id");
                    }
                }
            }

            // Define Name: private field, public property, and database column.
            private String _name;

            [Column]
            public String Name
            {
                get { return _name; }
                set
                {
                    if (_name != value)
                    {
                        NotifyPropertyChanging("Name");
                        _name = value;
                        NotifyPropertyChanged("Name");
                    }
                }
            }

            // Define Description: private field, public property, and database column.
            private String _description;

            [Column]
            public String Description
            {
                get { return _description; }
                set
                {
                    if (_description != value)
                    {
                        NotifyPropertyChanging("Description");
                        _description = value;
                        NotifyPropertyChanged("Description");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _startDate;

            [Column]
            public DateTime StartDate
            {
                get { return _startDate; }
                set
                {
                    if (_startDate != value)
                    {
                        NotifyPropertyChanging("StartDate");
                        _startDate = value;
                        NotifyPropertyChanged("StartDate");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _endDate;

            [Column]
            public DateTime EndDate
            {
                get { return _endDate; }
                set
                {
                    if (_endDate != value)
                    {
                        NotifyPropertyChanging("EndDate");
                        _endDate = value;
                        NotifyPropertyChanged("EndDate");
                    }
                }
            }

            // Define NumberOfDaysBeforeEndDate for the localVignette: private field, public property, and database column.
            private Int32 _numberOfDaysBeforeEndDate;

            [Column]
            public Int32 NumberOfDaysBeforeEndDate
            {
                get { return _numberOfDaysBeforeEndDate; }
                set
                {
                    if (_numberOfDaysBeforeEndDate != value)
                    {
                        NotifyPropertyChanging("NumberOfDaysBeforeEndDate");
                        _numberOfDaysBeforeEndDate = value;
                        NotifyPropertyChanged("NumberOfDaysBeforeEndDate");
                    }
                }
            }

            // Internal column for the associated car ID value
            [Column]
            internal int _carId;

            // Entity reference, to identify the Car "storage" table
            private EntityRef<Car> _car;

            // Association, to describe the relationship between this key and that "storage" table
            [Association(Storage = "_car", ThisKey = "_carId", OtherKey = "CarId", IsForeignKey = true)]
            public Car Car
            {
                get { return _car.Entity; }
                set
                {
                    NotifyPropertyChanging("Car");
                    _car.Entity = value;

                    if (value != null)
                    {
                        _carId = value.CarId;
                    }

                    NotifyPropertyChanging("Car");
                }
            }

            // Version column aids update performance.
            [Column(IsVersion = true)]
            private Binary _version;

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            #region INotifyPropertyChanging Members

            public event PropertyChangingEventHandler PropertyChanging;

            // Used to notify that a property is about to change
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }

            #endregion
        }

        [Table]
        public class ExtendedInsurance : INotifyPropertyChanged, INotifyPropertyChanging
        {

            // Define id: private field, public property, and database column.
            private int _id;

            [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int Id
            {
                get { return _id; }
                set
                {
                    if (_id != value)
                    {
                        NotifyPropertyChanging("Id");
                        _id = value;
                        NotifyPropertyChanged("Id");
                    }
                }
            }

            // Define Name: private field, public property, and database column.
            private String _name;

            [Column]
            public String Name
            {
                get { return _name; }
                set
                {
                    if (_name != value)
                    {
                        NotifyPropertyChanging("Name");
                        _name = value;
                        NotifyPropertyChanged("Name");
                    }
                }
            }

            // Define Description: private field, public property, and database column.
            private String _description;

            [Column]
            public String Description
            {
                get { return _description; }
                set
                {
                    if (_description != value)
                    {
                        NotifyPropertyChanging("Description");
                        _description = value;
                        NotifyPropertyChanged("Description");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _startDate;

            [Column]
            public DateTime StartDate
            {
                get { return _startDate; }
                set
                {
                    if (_startDate != value)
                    {
                        NotifyPropertyChanging("StartDate");
                        _startDate = value;
                        NotifyPropertyChanged("StartDate");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _endDate;

            [Column]
            public DateTime EndDate
            {
                get { return _endDate; }
                set
                {
                    if (_endDate != value)
                    {
                        NotifyPropertyChanging("EndDate");
                        _endDate = value;
                        NotifyPropertyChanged("EndDate");
                    }
                }
            }

            // Define NumberOfDaysBeforeEndDate for the localVignette: private field, public property, and database column.
            private Int32 _numberOfDaysBeforeEndDate;

            [Column]
            public Int32 NumberOfDaysBeforeEndDate
            {
                get { return _numberOfDaysBeforeEndDate; }
                set
                {
                    if (_numberOfDaysBeforeEndDate != value)
                    {
                        NotifyPropertyChanging("NumberOfDaysBeforeEndDate");
                        _numberOfDaysBeforeEndDate = value;
                        NotifyPropertyChanged("NumberOfDaysBeforeEndDate");
                    }
                }
            }

            // Internal column for the associated car ID value
            [Column]
            internal int _carId;

            // Entity reference, to identify the Car "storage" table
            private EntityRef<Car> _car;

            // Association, to describe the relationship between this key and that "storage" table
            [Association(Storage = "_car", ThisKey = "_carId", OtherKey = "CarId", IsForeignKey = true)]
            public Car Car
            {
                get { return _car.Entity; }
                set
                {
                    NotifyPropertyChanging("Car");
                    _car.Entity = value;

                    if (value != null)
                    {
                        _carId = value.CarId;
                    }

                    NotifyPropertyChanging("Car");
                }
            }

            // Version column aids update performance.
            [Column(IsVersion = true)]
            private Binary _version;

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            #region INotifyPropertyChanging Members

            public event PropertyChangingEventHandler PropertyChanging;

            // Used to notify that a property is about to change
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }

            #endregion
        }

        [Table]
        public class CustomDependency : INotifyPropertyChanged, INotifyPropertyChanging
        {

            // Define id: private field, public property, and database column.
            private int _id;

            [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int Id
            {
                get { return _id; }
                set
                {
                    if (_id != value)
                    {
                        NotifyPropertyChanging("Id");
                        _id = value;
                        NotifyPropertyChanged("Id");
                    }
                }
            }

            // Define Name: private field, public property, and database column.
            private String _name;

            [Column]
            public String Name
            {
                get { return _name; }
                set
                {
                    if (_name != value)
                    {
                        NotifyPropertyChanging("Name");
                        _name = value;
                        NotifyPropertyChanged("Name");
                    }
                }
            }

            // Define Description: private field, public property, and database column.
            private String _description;

            [Column]
            public String Description
            {
                get { return _description; }
                set
                {
                    if (_description != value)
                    {
                        NotifyPropertyChanging("Description");
                        _description = value;
                        NotifyPropertyChanged("Description");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _startDate;

            [Column]
            public DateTime StartDate
            {
                get { return _startDate; }
                set
                {
                    if (_startDate != value)
                    {
                        NotifyPropertyChanging("StartDate");
                        _startDate = value;
                        NotifyPropertyChanged("StartDate");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _endDate;

            [Column]
            public DateTime EndDate
            {
                get { return _endDate; }
                set
                {
                    if (_endDate != value)
                    {
                        NotifyPropertyChanging("EndDate");
                        _endDate = value;
                        NotifyPropertyChanged("EndDate");
                    }
                }
            }

            // Define NumberOfDaysBeforeEndDate for the localVignette: private field, public property, and database column.
            private Int32 _numberOfDaysBeforeEndDate;

            [Column]
            public Int32 NumberOfDaysBeforeEndDate
            {
                get { return _numberOfDaysBeforeEndDate; }
                set
                {
                    if (_numberOfDaysBeforeEndDate != value)
                    {
                        NotifyPropertyChanging("NumberOfDaysBeforeEndDate");
                        _numberOfDaysBeforeEndDate = value;
                        NotifyPropertyChanged("NumberOfDaysBeforeEndDate");
                    }
                }
            }

            // Internal column for the associated car ID value
            [Column]
            internal int _carId;

            // Entity reference, to identify the Car "storage" table
            private EntityRef<Car> _car;

            // Association, to describe the relationship between this key and that "storage" table
            [Association(Storage = "_car", ThisKey = "_carId", OtherKey = "CarId", IsForeignKey = true)]
            public Car Car
            {
                get { return _car.Entity; }
                set
                {
                    NotifyPropertyChanging("Car");
                    _car.Entity = value;

                    if (value != null)
                    {
                        _carId = value.CarId;
                    }

                    NotifyPropertyChanging("Car");
                }
            }

            // Version column aids update performance.
            [Column(IsVersion = true)]
            private Binary _version;

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            #region INotifyPropertyChanging Members

            public event PropertyChangingEventHandler PropertyChanging;

            // Used to notify that a property is about to change
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }

            #endregion
        }

        [Table]
        public class InternationalVignette : INotifyPropertyChanged, INotifyPropertyChanging
        {

            // Define id: private field, public property, and database column.
            private int _id;

            [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)]
            public int Id
            {
                get { return _id; }
                set
                {
                    if (_id != value)
                    {
                        NotifyPropertyChanging("Id");
                        _id = value;
                        NotifyPropertyChanged("Id");
                    }
                }
            }

            // Define CountryCode: private field, public property, and database column.
            private String _countryCode;

            [Column]
            public String CountryCode
            {
                get { return _countryCode; }
                set
                {
                    if (_countryCode != value)
                    {
                        NotifyPropertyChanging("CountryCode");
                        _countryCode = value;
                        NotifyPropertyChanged("CountryCode");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _startDate;

            [Column]
            public DateTime StartDate
            {
                get { return _startDate; }
                set
                {
                    if (_startDate != value)
                    {
                        NotifyPropertyChanging("StartDate");
                        _startDate = value;
                        NotifyPropertyChanged("StartDate");
                    }
                }
            }

            // Define startDate: private field, public property, and database column.
            private DateTime _endDate;

            [Column]
            public DateTime EndDate
            {
                get { return _endDate; }
                set
                {
                    if (_endDate != value)
                    {
                        NotifyPropertyChanging("EndDate");
                        _endDate = value;
                        NotifyPropertyChanged("EndDate");
                    }
                }
            }

            // Define NumberOfDaysBeforeEndDate for the localVignette: private field, public property, and database column.
            private Int32 _numberOfDaysBeforeEndDate;

            [Column]
            public Int32 NumberOfDaysBeforeEndDate
            {
                get { return _numberOfDaysBeforeEndDate; }
                set
                {
                    if (_numberOfDaysBeforeEndDate != value)
                    {
                        NotifyPropertyChanging("NumberOfDaysBeforeEndDate");
                        _numberOfDaysBeforeEndDate = value;
                        NotifyPropertyChanged("NumberOfDaysBeforeEndDate");
                    }
                }
            }

            // Internal column for the associated car ID value
            [Column]
            internal int _carId;

            // Entity reference, to identify the Car "storage" table
            private EntityRef<Car> _car;

            // Association, to describe the relationship between this key and that "storage" table
            [Association(Storage = "_car", ThisKey = "_carId", OtherKey = "CarId", IsForeignKey = true)]
            public Car Car
            {
                get { return _car.Entity; }
                set
                {
                    NotifyPropertyChanging("Car");
                    _car.Entity = value;

                    if (value != null)
                    {
                        _carId = value.CarId;
                    }

                    NotifyPropertyChanging("Car");
                }
            }

            // Version column aids update performance.
            [Column(IsVersion = true)]
            private Binary _version;

            #region INotifyPropertyChanged Members

            public event PropertyChangedEventHandler PropertyChanged;

            // Used to notify that a property changed
            private void NotifyPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                {
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
                }
            }

            #endregion

            #region INotifyPropertyChanging Members

            public event PropertyChangingEventHandler PropertyChanging;

            // Used to notify that a property is about to change
            private void NotifyPropertyChanging(string propertyName)
            {
                if (PropertyChanging != null)
                {
                    PropertyChanging(this, new PropertyChangingEventArgs(propertyName));
                }
            }

            #endregion
        }

    
}
